<!-- 菜单 - 树形结构 -->
<template>
    <div class="tree-container" :style="`max-height: ${mHeight}px;`">
        <el-tree
        ref="menusTreeRef"
        node-key="id"
        :data="treeData" 
        :props="defaultProps" 
        :show-checkbox="showCheckbox" 
        :expand-on-click-node="onClickNode"
        @node-click="treeNodeClick"
        :filter-node-method="filterNode"
        :check-strictly="checkStrictly"
        :default-expanded-keys="defaultExpandedKeys"
        :default-checked-keys="defaultCheckedKeys"
        :default-expand-all="defaultExpandAll"/>
    </div>
</template>

<script setup>
// ========================= 组件可接收的值 =========================
const treeInfo = defineProps({
    treeData: { // 数据
        type: Array,
        default: () => []
    },

    showCheckbox: { // 是否可选择
        type: Boolean,
        default:false
    },

    onClickNode: { // 点击节点，是否收缩节点
        type: Boolean,
        default:false
    },

    checkStrictly: { // 显示复选框的情况下，是否父子联动
        type: Boolean,
        default:false
    },

    defaultExpandAll: { // 是否默认展开所有节点
        type: Boolean,
        default:false
    },

    defaultExpandedKeys: { // 默认的展开
        type: Array,
        default: () => []
    },

    defaultCheckedKeys: { // 默认选中的节点
        type: Array,
        default: () => []
    },

    mHeight: {
        type: Number,
        default: 300
    },

    filterKey:String // 过滤
})
// ========================= 实列挂载之前调用 =========================
onBeforeMount(() => {
    
})

// ========================= 节点操作 =========================
// 节点点击
function treeNodeClick(data, node, component) {
    if(treeInfo.showCheckbox) return false;
    emits('nodeClick', data);
};

/**
 * 节点 - 展开/折叠
 * 
*/
function expandHandle(state) {
    // let rootNode = menusTreeRef.value.store.root;
    // expandNodes(rootNode, state);
    let rootNode = menusTreeRef.value.store.nodesMap;
    for(let nodeItem in rootNode) {
        rootNode[nodeItem].expanded = state;
    };
};
// function expandNodes(node, state) {
//     node.expanded = state;
//     for (let i = 0; i < node.childNodes.length; i++) {
//         node.childNodes[i].expanded = state;
//         if (node.childNodes[i].childNodes.length > 0) {
//             expandNodes(node.childNodes[i], state);
//         };
//     };
// };

/**
 *  设置选中节点
 * key: 要选中的节点的 key 或者数据
 * checked: 一个布尔类型参数表明是否选中
 * deepChecked: 一个布尔类型参数表明是否递归选中子节点
*/
function setChecked(key, checked, deepChecked) {
    menusTreeRef.value.setChecked(key, checked, deepChecked);
};
// 重置选中节点
function resetChecked() {
    menusTreeRef.value.setCheckedKeys([]);
};

/**
 * 获取当前选中节点 key 的数组
 * type: 布尔类型参数，默认为 false. 如果参数是 true, 它只返回当前选择的子节点数组。
 * 
*/
function getCheckedKeys(type = false) {
    return menusTreeRef.value.getCheckedKeys(type);
};

// ========================= 过滤 =========================
const menusTreeRef = ref();
watch( // 监听
    () => treeInfo.filterKey,
    (newVal, oldVal) => {
        menusTreeRef.value.filter(newVal);
    },
    // () => treeInfo.defaultExpendKeys,
    // (newVal, oldVal) => {
    //     console.log(newVal)
    // },
);
const filterNode = (value, data) => {
  if (!value) return true;
  return data.title.includes(value);
}


// ========================= 定义发射给父组件的方法 =========================
const emits = defineEmits(['nodeClick'])

// ========================= 向外暴露方法或属性 =========================
defineExpose({
    setChecked,
    resetChecked,
    getCheckedKeys,
    expandHandle
});


const defaultProps = {
    children: 'children',
    label: 'title',
};
</script>

<style lang="scss" scoped>
.tree-container {
    overflow-y: auto;
}
</style>